
#ifndef _TERMINATORBASE_H__INCLUDED_
#define _TERMINATORBASE_H__INCLUDED_

#include "ManagedService.h"
#include "BuiltinTask.h"

namespace nebula { namespace sdk {

class TerminatorBase : public sdk::ManagedService<TerminatorBase>
{
public:
	TerminatorBase();

public:
	//////////////////////////////////////////////////////////////////////////
	//TaskBase required event handlers
	virtual NEBULA_ERROR_CODE OnInitialize () = 0;
	virtual void              OnFinalize   () = 0; 
	virtual NEBULA_ERROR_CODE OnStart      () = 0;
	virtual void              OnStop       () = 0;

protected:

	//Inherit classes should call this function in OnInitialize() event handler
	// to ensure the terminator is initialized properly
	NEBULA_ERROR_CODE InitializeTerminator();

	//Inherit classes should call this function in OnFinalize() event handler
	// to ensure the storage is finalized properly
	NEBULA_ERROR_CODE FinalizeTerminator();

	NEBULA_ERROR_CODE StartTerminator();

	NEBULA_ERROR_CODE StopTerminator();

	//Inherit classes could call this function in OnTaskTerminate() event handler
	// to add a handled task to meta queue
	NEBULA_ERROR_CODE PushToMetaQueue(ITask* task);

	//This virtual member will be called once the task is received
	// default behavior of this event handler is empty
	// rewrite the virtual function to describe customized process
	//Note: client code could modify the task content but not release task resource 
	virtual NEBULA_ERROR_CODE OnTaskRcved (MetaOnlyTask *ptask);

	//This virtual member will be called before the task is terminated
	// default behavior of this event handler is empty
	// rewrite the virtual function to describe customized process
	//
	//Note: client code should return NEBULA_ERR_SUCCESS to identify a
	// successfully terminate operation over the task. Otherwise, the default
	// behavior of adding a meta only task to the meta queue will be fulfilled
	virtual NEBULA_ERROR_CODE OnTaskTerminate(MetaOnlyTask *ptask);

private:
	NEBULA_ERROR_CODE MetaHandler(std::auto_ptr<nebula::sdk::ITask>);
	NEBULA_ERROR_CODE HandleTask(MetaOnlyTask* ptask);

private:
	static const char* get_generator_nodename(nebula::sdk::MetaOnlyTask*);
	static bool ack_filter(IService*, const char*, const nebula::sdk::ITask*);

private:
	sdk::IDoneTaskQueue* _ack_queue;
	sdk::IDoneTaskQueue* _ack2_queue;
	sdk::IDoneTaskQueue* _log_queue;
};

}} // end namespace ngmp::sdk

#endif // _TERMINATORBASE_H__INCLUDED_
